﻿using System;
using System.Security.Cryptography;
using System.Text;

namespace Douyu.Common
{
    /// <summary>
    /// 公用函数库
    /// </summary>
    public static class Utils
    {
        public const long UnixEpoch = 621355968000000000L;

        /// <summary>
        /// 获取UnixTime
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static long ToUnixTime(this DateTime time)
        {
            return (time.ToUniversalTime().Ticks - UnixEpoch) / TimeSpan.TicksPerSecond;
        }

        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string ToMD5(this string data)
        {
            using (var md5 = new MD5CryptoServiceProvider())
            {
                var byteValues = Encoding.Default.GetBytes(data);
                var byteHashs = md5.ComputeHash(byteValues);

                md5.Clear();
                string sTemp = "";
                for (int i = 0; i < byteHashs.Length; i++)
                {
                    sTemp += byteHashs[i].ToString("X").PadLeft(2, '0');
                }
                return sTemp.ToUpper();
            }
        }

        /// <summary>
        /// 是否为64位系统
        /// </summary>
        /// <returns></returns>
        public static bool Is64bit()
        {
            return Environment.Is64BitOperatingSystem;
        }

        /// <summary>
        /// 是否为32位系统
        /// </summary>
        /// <returns></returns>
        public static bool Is32bit()
        {
            return !Environment.Is64BitOperatingSystem;
        }

        /// <summary>
        /// 交换两个对象
        /// </summary>
        /// <param name="o1"></param>
        /// <param name="o2"></param>
        public static void Swap(ref object o1, ref object o2)
        {
            var ot = o1;
            o1 = o2;
            o2 = ot;
        }

        /// <summary>
        /// 交换两个类对象
        /// </summary>
        /// <param name="o1"></param>
        /// <param name="o2"></param>
        public static void Swap<T>(ref T o1, ref T o2)
        {
            T ot = o1;
            o1 = o2;
            o2 = ot;
        }

        /// <summary>
        /// 多路选择函数：索引值对应的值.
        /// <para>溢出时，使用默认值.</para>
        /// </summary>
        /// <param name="index">索引值</param>
        /// <param name="defaultvalue">默认值</param>
        /// <param name="values">候选值</param>
        /// <returns></returns>
        public static T Cast<T>(this int index, T defaultvalue, params T[] values)
        {
            if (index >= 0 || index < values.Length)
            {
                return values[index];
            }
            else
            {
                return defaultvalue;
            }
        }

        /// <summary>
        /// 多路选择函数：索引值对应的值.
        /// <para>溢出时，以溢出方向取最后一个边界值.</para>
        /// </summary>
        /// <param name="index">索引值</param>
        /// <param name="values">候选值</param>
        /// <returns></returns>
        public static T Range<T>(this int index, params T[] values)
        {
            if (index < 0) index = 0;
            if (index > values.Length) index = values.Length;
            return values[index];
        }

    }
}
